<script setup lang='ts'>
import dayjs from 'dayjs';

interface Props {
  data: ISportEventInfo
}

defineOptions({ name: 'AppSportsMarketInfo' })
const props = defineProps<Props>()
console.log("🚸🚸🚸 ~ props:", props.data)

const sportsStore = useSportsStore()
const { sportsFavoriteData } = storeToRefs(sportsStore)
const marketInfoRef = useTemplateRef<HTMLElement>('marketInfoRef')
const { isLogin, currentGlobalCurrency } = storeToRefs(useAppStore())
/** 是否收藏 */
const { bool: isFavorite } = useBoolean(false)
const { bool: playUnActiveAnimate } = useBoolean(false)


/** 添加收藏 */
const { run: runAddFavorite } = useRequest(() =>
  ApiSportAddFavorite({
    si: props.data.si,
    eis: [props.data.ei],
    cur: currencyConfig[currentGlobalCurrency.value].cur,
  }),
  {
    onSuccess() {
      isFavorite.value = true
      sportsStore.refreshSportsFavList()
    },
    loadingKeep: 0,
  })
/** 删除收藏 */
const { run: runDelFavorite } = useRequest(() =>
  ApiSportDelFavorite({
    si: props.data.si,
    eis: [props.data.ei],
    cur: currencyConfig[currentGlobalCurrency.value].cur,
  }),
  {
    onSuccess() {
      isFavorite.value = false
      sportsStore.refreshSportsFavList()
    },
    loadingKeep: 0,
  })

/** 盘口相关 */
// 默认展示标准盘
const mainMarketData = computed(() => {
  const arr = props.data.ml.filter(a => a.bt === 3 || a.bt === 4)
  return arr.length > 0 ? arr[0] : props.data.ml[0]
})
// 第一个盘的下注按钮
const mainMarketBtns = computed(() => {
  return mainMarketData.value.ms.map((a) => {
    let title = ''
    // 让球
    if (mainMarketData.value.bt === 1)
      title = `(${a.hdp}) ${a.sn}`
    // 总分
    else if (mainMarketData.value.bt === 2)
      title = `${a.sn} ${a.hdp}`
    // 独赢
    else if (mainMarketData.value.bt === 3 || mainMarketData.value.bt === 4)
      title = a.sn

    return {
      title,
      ...a,
      disabled: mainMarketData.value.mls !== 1,
      cartInfo: getCartObject(mainMarketData.value, a, props.data),
    }
  })
})
// 更多盘口
const moreMarketList = computed(() => {
  if (props.data.qml && props.data.qml.length > 0) {
    const arr = []
    // 第一层 n: "让球&大小"
    for (let i = 0; i < props.data.qml.length; i++) {
      // 第二层 n: "全场"
      for (let ii = 0; ii < props.data.qml[i].sqml.length; ii++) {
        // 第三层
        for (let iii = 0; iii < props.data.qml[i].sqml[ii].ml.length; iii++) {
          arr.push(toRaw(props.data.qml[i].sqml[ii].ml[iii]))
        }
      }
    }
    const _arr = arr.map((a) => {
      // 波胆
      const isBodan = a.bt === 158 || a.bt === 6
      if (isBodan) {
        const msMaped = a.ms.map((c) => {
          return {
            ...c,
            title: c.sn,
            disabled: a.mls !== 1,
            cartInfo: getCartObject(a, c, props.data),
          }
        })
        const arr1 = msMaped.filter((d) => {
          const strArr = d.sn.split('-')
          return +strArr[0] > +strArr[1]
        })
        const arr2 = msMaped.filter((d) => {
          const strArr = d.sn.split('-')
          return +strArr[0] === +strArr[1] || strArr.length === 1
        })
        const arr3 = msMaped.filter((d) => {
          const strArr = d.sn.split('-')
          return +strArr[0] < +strArr[1]
        })

        return {
          ...a,
          title: `${a.pn} - ${a.btn}`,
          isBodan,
          ms: msMaped,
          msCol1: arr1,
          msCol2: arr2,
          msCol3: arr3,
          msRow: [],
        }
      }

      return {
        ...a,
        title: `${a.pn} - ${a.btn}`,
        isBodan: false,
        ms: a.ms.map((b) => {
          let title = ''
          // 让球
          if (a.bt === 1)
            title = `(${b.hdp}) ${b.sn}`
          // 总分
          else if (a.bt === 2)
            title = `${b.sn} ${b.hdp}`
          // 独赢
          else if (a.bt === 3 || a.bt === 4)
            title = b.sn

          return {
            ...b,
            title,
            disabled: a.mls !== 1,
            cartInfo: getCartObject(a, b, props.data),
          }
        }),
        msCol1: [],
        msCol2: [],
        msCol3: [],
        msRow: [],
      }
    })
    // console.log("🚸🚸🚸 ~ moreMarketList ~ arr:", _arr)
    return _arr
  }
  return []
})

// 详情路径
const eventDetailPath = computed(() => {
  const data = props.data
  return `/sports/${SPORTS_PLAT_ID}/${data.si}/${data.pgid}/${data.ci}/${data.ei}`
})
// 是否已经开赛
const isStarted = computed(() => dayjs().isAfter((props.data.ed * 1000)))
// 正在滚球
const isOnAir = computed(() => props.data.m === 3)
// 赛事暂停
const isTimeout = computed(() => props.data.rbts === 3)
const timeText = computed(() => formatTimeWithDayLabel(props.data.ed))
// 赛事进行时间
const eventTime = computed(() => {
  const minute = props.data.rbtt.split(':')[0]
  return minute ? minute + '′' : ''
})

// 操作收藏
function favHandler() {
  if (isFavorite.value)
    runDelFavorite()

  else
    runAddFavorite()
}
function onAnimationend() {
  if (playUnActiveAnimate.value)
    playUnActiveAnimate.value = false
}

// 跳转联赛
function onLeagueNameClick() {
  i18nNavigateTo(getSportsRoutePath({
    page: '/sport',
    si: `${props.data.si}`,
    ci: props.data.ci,
    cn: props.data.cn,
    pgid: props.data.pgid
  }))
}

watch(sportsFavoriteData, (a) => {
  if (a && a.d)
    isFavorite.value = a.d.findIndex(a => a.ei === props.data.ei) > -1
})
watch(isFavorite, (a) => {
  if (!a) {
    playUnActiveAnimate.value = true
  }
})

onMounted(() => {
  if (sportsFavoriteData.value && sportsFavoriteData.value.d) {
    const fl = sportsFavoriteData.value.d
    isFavorite.value = fl.findIndex(a => a.ei === props.data.ei) > -1
  }
})

// #region 🚧🚧 查看更多相关 🚧🚧
// 是否展开
const isShowMore = ref(false)
// 更多盘口高度
const showMoreListHeight = ref('0px')
const observerDomRef = ref()
const { height: observerHeight } = useElementSize(observerDomRef)
// 滚动状态
const isShowMoreAtTop = ref(true)
const isShowMoreAtBottom = ref(false)
// 是否展示更多盘口的mask
const isShowMoreScrollMask = ref(false)

// 打开与关闭更多
function toggleShowMore() {
  if (!isShowMore.value) {
    // 打开
    isShowMore.value = true
    isShowMoreScrollMask.value = true
    setTimeout(() => {
      showMoreListHeight.value = `${observerHeight.value}px`
    }, 0);
  }
  else {
    // 关闭
    showMoreListHeight.value = '0px'
  }
}
function onShowMoreTransitionend() {
  if (showMoreListHeight.value === '0px') {
    // 关闭
    resetShowMore()
  }
  else {
    // 打开
    nextTick(() => {
      if (observerHeight.value < 302) {
        isShowMoreScrollMask.value = false
      }
    })
  }
}
// 强制关闭
function closeShowMore() {
  if (!isShowMore.value)
    return
  showMoreListHeight.value = '0px'
}
// 重置状态
function resetShowMore() {
  isShowMore.value = false
  isShowMoreScrollMask.value = false
  isShowMoreAtTop.value = true
  isShowMoreAtBottom.value = false
}
// 更多盘口滚动事件
function onSimplebarScroll(e: Event) {
  const target = e.target as HTMLElement

  const scrollTop = target.scrollTop
  const scrollHeight = target.scrollHeight
  const clientHeight = target.clientHeight

  isShowMoreAtTop.value = scrollTop === 0
  isShowMoreAtBottom.value = scrollTop + clientHeight >= scrollHeight - 1 // 容错1px防抖
}
// 点击外部时
onClickOutside(marketInfoRef, closeShowMore)
// #endregion 🚧🚧 查看更多相关 🚧🚧
</script>

<template>
  <div ref="marketInfoRef" class="app-sports-market-info" :class="{ 'is-show-more': isShowMore }">
    <div class="wrapper">
      <!-- 上部分 -->
      <div class="top">
        <div class="left">
          <div class="info">
            <div class="w-full leading-[16px]">
              <!-- 联赛 -->
              <span class="title" @click="onLeagueNameClick">
                <span class="inline-flex items-center justify-center mr-[4px] w-[16px] h-[16px] p-[2px] flex-none">
                  <AppImage :url="data.spic" is-network>
                    <BaseIcon class="text-[16px]" name="uni-vector" />
                  </AppImage>
                </span>
                <span class="h-[16px] flex overflow-hidden break-all items-center leading-[16px] tracking-[0.03em]">
                  {{ data.pgn }}
                  <BaseIcon :has-transition="false" name="uni-triangle" class="text-[8px] rotate-270 m-[2px]" />
                  {{ data.cn }}
                </span>
              </span>
            </div>
          </div>
        </div>
        <!-- 收藏 -->
        <div v-if="isLogin" class="right" @click="favHandler" @animationend="onAnimationend"
          :class="{ active: isFavorite, unActive: playUnActiveAnimate }">
          <BaseIcon name="sports-fav" />
        </div>
      </div>
      <!-- 中 -->
      <div class="content">
        <!-- 状态 -->
        <div class="flex gap-[4px] h-[16px] pointer-events-none">
          <div class="flex-none flex">
            <div class="text-[12px] font-semibold leading-[16px] whitespace-nowrap tracking-[0.24px] align-middle "
              :class="isStarted ? 'text-[#21a8f7]' : 'opacity-50'">
              <!-- 开赛时间 -->
              <div v-if="!isStarted" class="text-[12px] break-all leading-[16px] tracking-[0.03em] align-middle">
                {{ timeText }}
              </div>
              <!-- 比赛开始 -->
              <span v-else-if="isStarted && !isOnAir">
                {{ $t('spt_started') }}
              </span>
              <!-- 开始滚球 -->
              <span v-else-if="isOnAir">
                <span v-show="eventTime && !isTimeout">{{ eventTime }}</span> {{ data.rbtd }}
              </span>
            </div>
          </div>
          <div class="flex items-center gap-[4px] grow text-[16px]">
          </div>
          <div v-if="isOnAir" class="flex-none ml-0 mr-[8px] flex items-center pointer-events-auto text-[16px]">
            <BaseIcon name="sports-live" style="--tg-base-icon-color:#fc3c3c;" />
          </div>
        </div>

        <div class="flex-1 mt-[12px] pointer-events-none flex overflow-hidden relative box-border">
          <!-- 主客队 -->
          <div class="flex-1 font-semibold">
            <!-- 主 -->
            <div class="flex items-center mb-[8px]">
              <div class="flex-1 h-[24px] flex relative text-[14px] items-center leading-[24px]">
                <div class="w-[24px] h-[24px] flex-none flex items-center mr-[8px]">
                  <AppImage :url="data.htpic" is-network>
                    <BaseIcon class="text-[20px]" name="uni-vector" />
                  </AppImage>
                </div>
                <div
                  class="h-[24px] leading-[24px] w-full inline-block overflow-hidden box-border break-all align-middle mask-image">
                  {{ data.htn }}
                </div>
              </div>
            </div>
            <!-- 客 -->
            <div class="flex items-center">
              <div class="flex-1 h-[24px] flex relative text-[14px] items-center leading-[24px]">
                <div class="w-[24px] h-[24px] flex items-center flex-none mr-[8px]">
                  <AppImage :url="data.atpic" is-network>
                    <BaseIcon class="text-[20px]" name="uni-vector" />
                  </AppImage>
                </div>
                <div
                  class="h-[24px] leading-[24px] w-full inline-block overflow-hidden box-border break-all align-middle mask-image">
                  {{ data.atn }}
                </div>
              </div>
            </div>
          </div>
          <!-- 比分 -->
          <div class="flex-none font-semibold">
            <div v-show="isStarted"
              class="grid gap-[8px] text-[14px] box-border place-items-center grid-flow-col grid-rows-2">
              <div class="score-item">
                <span>{{ data.hp }}</span>
              </div>
              <div class="score-item">
                <span>{{ data.ap }}</span>
              </div>
            </div>
          </div>
        </div>
      </div>
      <!-- 下 -->
      <div>
        <div class="bottom1">
          <div class="market-name">
            {{ mainMarketData.btn }}
          </div>
        </div>
        <div class="flex mt-[8px] items-end">
          <div class="flex-1 relative">
            <div class="w-full grid gap-[8px]"
              :style="`grid-template-columns: repeat(${mainMarketBtns.length}, minmax(0, 1fr));`">
              <AppSportsBetButton v-for="market in mainMarketBtns" size="big" :key="market.wid + market.sn"
                :odds="market.ov" :title="market.title" :disabled="market.disabled" :cart-info="market.cartInfo" />
            </div>
          </div>
          <div class="show-more" @click="toggleShowMore">
            <div class="icon" :class="{ up: isShowMore }">
              <BaseIcon name="uni-triangle" />
            </div>
          </div>
        </div>
        <!-- 更多 -->
        <div class="relative">
          <BaseSportsScrollbar class="max-h-[302px] overflow-x-hidden" @scroll="onSimplebarScroll">
            <div v-show="isShowMore" class="more-market" :style="{ height: showMoreListHeight }"
              @transitionend="onShowMoreTransitionend">
              <div ref="observerDomRef" class="overflow-hidden">
                <div v-for="moreMarketObj in moreMarketList" :key="moreMarketObj.mlid" class="relative">
                  <div class="label">
                    <div class="name">
                      {{ moreMarketObj.title }}
                    </div>
                  </div>
                  <div v-if="[1, 2, 7].includes(moreMarketObj.pat)" class="grid w-full gap-[8px] grid-cols-2">
                    <AppSportsBetButton v-for="moreBtn in moreMarketObj.ms" size="big" :key="moreBtn.wid + moreBtn.sn"
                      :odds="moreBtn.ov" :title="moreBtn.title" :disabled="moreBtn.disabled"
                      :cart-info="moreBtn.cartInfo" />
                  </div>
                  <template v-else-if="[3, 4, 5, 6].includes(moreMarketObj.pat)">
                    <div class="grid w-full gap-[8px] grid-cols-3 mb-[6px]">
                      <span class="text-[12px] text-center opacity-50 leading-[16px] text-[var(--color-text-white-0)]">
                        {{ data.htn }}
                      </span>
                      <span class="text-[12px] text-center opacity-50 leading-[16px] text-[var(--color-text-white-0)]">
                        {{ $t('spt_tie') }}
                      </span>
                      <span class="text-[12px] text-center opacity-50 leading-[16px] text-[var(--color-text-white-0)]">
                        {{ data.atn }}
                      </span>
                    </div>
                    <div v-if="moreMarketObj.isBodan" class="grid w-full gap-[8px] grid-cols-3">
                      <div class="flex flex-col">
                        <AppSportsBetButton class="not-last-of-type:mb-[8px]" v-for="btn in moreMarketObj.msCol1" size="big" :key="btn.wid + btn.sn"
                          :odds="btn.ov" :title="btn.title" :disabled="btn.disabled" :cart-info="btn.cartInfo" />
                      </div>
                      <div class="flex flex-col">
                        <AppSportsBetButton class="not-last-of-type:mb-[8px]" v-for="btn in moreMarketObj.msCol2" size="big" :key="btn.wid + btn.sn"
                          :odds="btn.ov" :title="btn.title" :disabled="btn.disabled" :cart-info="btn.cartInfo" />
                      </div>
                      <div class="flex flex-col">
                        <AppSportsBetButton class="not-last-of-type:mb-[8px]" v-for="btn in moreMarketObj.msCol3" size="big" :key="btn.wid + btn.sn"
                          :odds="btn.ov" :title="btn.title" :disabled="btn.disabled" :cart-info="btn.cartInfo" />
                      </div>
                    </div>
                    <div v-else class="grid w-full gap-[8px] grid-cols-3">
                      <AppSportsBetButton v-for="moreBtn in moreMarketObj.ms" size="big" :key="moreBtn.wid + moreBtn.sn"
                      :odds="moreBtn.ov" :title="moreBtn.title" :disabled="moreBtn.disabled"
                      :cart-info="moreBtn.cartInfo" />
                    </div>
                  </template>
                </div>
              </div>
            </div>
          </BaseSportsScrollbar>
          <div class="mask-top" :class="{ 'no-show': isShowMoreAtTop || !isShowMoreScrollMask }" />
          <div class="mask-bottom" :class="{ 'no-show': isShowMoreAtBottom || !isShowMoreScrollMask }" />
        </div>
      </div>
    </div>
  </div>
</template>

<style lang='scss' scoped>
.mask-image {
  mask-image: linear-gradient(90deg, rgba(0, 0, 0, 1) 80%, rgba(0, 0, 0, 0) 100%);
}

.app-sports-market-info {
  height: 204px;
  direction: ltr;
  position: relative;
  vertical-align: top;

  &.is-show-more {
    z-index: 9;

    .wrapper {
      top: 0;
      left: 0;
      position: absolute;
      box-shadow: 0 0 100px rgba(0, 0, 0, 0.65);
      max-height: max-content;
    }
  }

  .wrapper {
    color: var(--color-text-white-0);
    width: 100%;
    border: 1px solid transparent;
    opacity: 1;
    padding: 12px 8px 8px;
    background: var(--color-bg-black-3);
    box-sizing: border-box;
    max-height: 204px;
    min-height: 100%;
    border-color: var(--color-bg-black-3);
    border-radius: 8px;
  }

  .top {
    display: flex;
    position: relative;
    font-size: 10px;
    padding-left: 8px;
    padding-right: 8px;

    .left {
      flex: 1;
      height: 16px;
      display: flex;
      overflow: hidden;
      position: relative;
      font-size: 12px;
      box-sizing: border-box;
      text-align: left;
      word-break: break-all;
      line-height: 16px;

      .info {
        width: 100%;
        overflow: hidden;
        mask-image: linear-gradient(90deg, rgba(0, 0, 0, 1) 80%, rgba(0, 0, 0, 0) 100%);
        white-space: nowrap;

        .title {
          width: 100%;
          line-height: 16px;
          color: rgba(255, 255, 255, 0.5);
          height: 16px;
          display: flex;
          font-size: 12px;
          align-items: center;
          font-weight: 600;
          -webkit-font-smoothing: antialiased;
          --tg-base-icon-color: rgba(255, 255, 255, 0.5);

          @media (hover: hover) and (pointer: fine) {
            &:hover {
              color: rgb(255, 255, 255);
              cursor: pointer;
              transition:
                color,
                opacity 0.3s;
              --tg-base-icon-color: rgb(255, 255, 255);
            }
          }
        }
      }
    }

    .right {
      font-size: 16px;
      cursor: pointer;
      display: flex;
      align-items: center;
      margin-left: 4px;
      opacity: 0.4;

      &.active {
        opacity: 1;
        --tg-base-icon-color: #FFBE3E;
        animation: bt44063 0.55s linear both;
      }

      &.unActive {
        animation: bt44064 0.55s linear both;
      }

      @media (hover: hover) and (pointer: fine) {
        &:hover:not(.active) {
          opacity: 1;
          --tg-base-icon-color: #fff;
        }
      }
    }
  }

  .content {
    color: var(--color-text-white-0);
    border: none;
    cursor: pointer;
    display: flex;
    padding: 8px 0 12px 8px;
    background: none;
    transition: all 0.2s ease-in-out;
    border-color: var(--color-bg-black-5);
    border-radius: 6px;
    flex-direction: column;
    text-decoration: none;

    .score-item {
      color: var(--color-text-white-0);
      border: 1px solid rgba(255, 255, 255, 0.1);
      height: 24px;
      display: flex;
      padding: 4px;
      font-size: 14px;
      min-width: 32px;
      background: rgba(255, 255, 255, 0.05);
      box-sizing: border-box;
      align-items: center;
      font-weight: 600;
      line-height: 16px;
      border-radius: 8px;
      justify-content: center;
    }
  }

  .bottom1 {
    width: auto;
    text-align: left;
    padding-left: 8px;
    color: var(--color-text-white-0);
    margin: 0;
    z-index: 4;
    position: relative;
    background: var(--color-bg-black-3);
    box-sizing: border-box;
    font-weight: 600;

    .market-name {
      width: 100%;
      height: 16px;
      opacity: 0.5;
      overflow: hidden;
      font-size: 12px;
      box-sizing: border-box;
      line-height: 16px;
      border-radius: 2px;
      mask-image: linear-gradient(90deg, rgba(0, 0, 0, 1) 80%, rgba(0, 0, 0, 0) 100%);
    }
  }

  .show-more {
    color: var(--color-text-white-0);
    width: 32px;
    cursor: pointer;
    height: 40px;
    display: flex;
    background: var(--color-bg-black-5);
    box-sizing: border-box;
    transition: all 0.3s ease-in-out;
    align-items: center;
    font-weight: 600;
    margin-left: 8px;
    border-color: var(--color-bg-black-5);
    border-radius: 8px;
    justify-content: center;

    @media (hover: hover) and (pointer: fine) {
      &:hover {
        color: #ffffff;
        cursor: pointer;
        background: rgba(0, 0, 0, 0.05);
        border-color: rgba(0, 0, 0, 0.05);
      }
    }

    .icon {
      display: flex;
      transition: all 0.3s;
      align-items: center;
      justify-content: center;
      opacity: 0.5;
      font-size: 16px;

      &.up {
        transform: rotate(-180deg);
      }
    }
  }

  .more-market {
    overflow: hidden;
    transition: height 0.35s linear;
    padding-bottom: 8px;
    box-sizing: content-box;

    .label {
      color: var(--color-text-white-0);
      margin: 0;
      z-index: 4;
      position: relative;
      background: var(--color-bg-black-3);
      box-sizing: border-box;
      font-weight: 600;
      margin-top: 16px;
      text-align: left;
      padding-left: 8px;
      margin-bottom: 8px;

      .name {
        width: 100%;
        height: 16px;
        opacity: 0.5;
        overflow: hidden;
        font-size: 12px;
        box-sizing: border-box;
        line-height: 16px;
        border-radius: 2px;
        mask-image: linear-gradient(90deg, rgba(0, 0, 0, 1) 80%, rgba(0, 0, 0, 0) 100%);
      }
    }
  }

  .mask-top {
    top: 0px;
    left: 0px;
    width: 100%;
    height: 32px;
    z-index: 1;
    position: absolute;
    transform-origin: center top;
    background: linear-gradient(rgb(41, 45, 46) 0%, rgb(41, 45, 46) 25%, rgba(41, 45, 46, 0) 100%);
    transition:
      transform 0.3s linear,
      opacity;
    pointer-events: none;

    &.no-show {
      opacity: 0;
      transform: scaleY(0);
    }
  }

  .mask-bottom {
    left: 0px;
    width: 100%;
    bottom: 0px;
    height: 32px;
    z-index: 1;
    position: absolute;
    transform-origin: center bottom;
    background: linear-gradient(0deg, rgb(41, 45, 46) 0%, rgb(41, 45, 46) 25%, rgba(41, 45, 46, 0) 100%);
    transition:
      transform 0.3s linear,
      opacity;
    pointer-events: none;

    &.no-show {
      opacity: 0;
      transform: scaleY(0);
    }
  }
}


@keyframes bt44063 {
  0% {
    transform: scale(1);
  }

  35% {
    transform: scale(1.3);
  }

  60% {
    transform: scale(1.4);
  }

  90% {
    transform: scale(0.9);
  }

  100% {
    transform: scale(1);
  }
}

@keyframes bt44064 {
  0% {
    transform: scale(1);
  }

  35% {
    transform: scale(0.7);
  }

  50% {
    transform: scale(0.6);
  }

  65% {
    transform: scale(0.7);
  }

  100% {
    transform: scale(1);
  }
}
</style>
